home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdFileTools.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
19KB
|
678 lines
(*************************************************************************
:Program. EdFileTools.mod
:Contents. File-Management for AmokEd
:Author. Hartmut Goebel
:Language. Oberon
:Translator. Amiga Oberon Compiler V2.00
:Imports. Printf (Volker Rudolph)
:History. V0.1, 25 Sep 1990 Hartmut Goebel
:History. V1.0, 14 Apr 1991 Hartmut Goebel [hG]
:History. V1.0b 22 Apr 1991 [hG] Source-Bug in LoadLines removed
:History. V1.1 22 Apr 1991 [hG] +doSaveConfig, GetConfig
:History. V1.2 11 Jun 1991 [hg], Volker Rudolph: +_Fast_LoadLines etc.
:History. V1.2b 21 Oct 1991 [hg] - Bug in ArpLoad (File/path-Split)
:Date. 21 Oct 1991 12:26:24
*************************************************************************)
MODULE EdFileTools;
IMPORT
ASCII, Printf,
EdGadgets,
asl: ASL,
d : Dos,
e : Exec,
edB: EdBlocks,
edD: EdDisplay,
edE: EdErrors,
edG: EdGlobalVars,
edK: EdKeyboard,
edL: EdLowLevel,
fs : EdFileSystem,
g : Graphics,
I : Intuition,
lst: EdLists,
ol : OberonLib,
str: Strings,
sys: SYSTEM,
u : Utility;
(*------------------------------------------------------------------------*)
(* $Debug- *)
CONST
newFile*=0; (* NewFile oder InsFile } müssen unterschiedlich *)
saveAs*=1; (* SaveAs oder SaveOld } sein wegen ArpLoad/Save *)
saveBlock* = 2;
sourceDoNotTitle* = 3;
saveSysMap* = 0;
NewFile*="NEWFILE";
InsFile*="INSFILE";
SaveAs*="SAVEAS";
SaveOld*="SAVEOLD";
SaveBlock*="SAVEBLOCK";
Loading = "Loading...";
Saving = "Saving...";
FileNotFound = "File Not Found";
UnableToOpenFile = "Unable to open file";
ReadError = "Read Error!!";
WriteFailed = "Write failed!";
FileReqNotAvailable ="File Requester not available";
UnableToCD = "Unable to CD";
ConfigFileName = "s:AmokEd.config";
ReqBody = I.IntuiText(0,1,g.jam2,12,8,NIL,
sys.ADR("Delete modified Image?"),NIL);
ReqOkay = I.IntuiText(0,1,g.jam2,6,3,NIL,sys.ADR(edG.Okay),NIL);
ReqCancel = I.IntuiText(0,1,g.jam2,6,3,NIL,sys.ADR(edG.Cancel),NIL);
VAR
arpbase: e.LibraryPtr;
CONST
longDSize = 255;
longFSize = 126;
longPath = 0;
TYPE
DirName = ARRAY longDSize+1 OF CHAR;
FileName = ARRAY longFSize+1 OF CHAR;
DirNamePtr = POINTER TO DirName;
FileNamePtr = POINTER TO FileName;
VAR
Dirname: DirName; (* wird auch als Buffer für SaveLines benutzt *)
Filename: FileName;
TYPE
FileRequester = STRUCT
hail : e.ADDRESS; (* Hailing text *)
file : FileNamePtr; (* Filename array (FCHARS + 1) *)
dir : DirNamePtr; (* Directory array (DSIZE + 1) *)
window : I.WindowPtr; (* Window requesting or NULL *)
funcFlags : SHORTSET; (* Set bitdef's below *)
flags2 : SHORTSET; (* New flags... *)
function : PROCEDURE; (* Your function, see bitdef's *)
leftEdge : INTEGER; (* To be used later... *)
topEdge : INTEGER;
reserved : ARRAY 3 OF INTEGER;
argList : LONGINT;
userData : e.ADDRESS;
END;
FileRequesterPtr = POINTER TO FileRequester;
(*------------------------------------------------------------------------*)
PROCEDURE FileRequest {arpbase,-294}(fr{8}:FileRequesterPtr): BOOLEAN;
(*------------------------------------------------------------------------*)
PROCEDURE FileReq*(hail: edG.StringPtr): BOOLEAN;
TYPE
NineTags = ARRAY 9 OF u.TagItem;
VAR
i,j: INTEGER;
FR: FileRequester;
fr: asl.FileRequesterPtr;
tags: NineTags;
res: BOOLEAN;
BEGIN
LOOP
j := str.Length(Filename);
WHILE (j>=0) AND (Filename[j]#":") AND (Filename[j]#"/") DO DEC(j) END;
IF j >= 0 THEN
str.Cut(Filename,0,j,Dirname);
str.Delete(Filename,0,i);
END;
IF asl.asl#NIL THEN
tags := NineTags(asl.hail,NIL,asl.window,NIL,
asl.file,NIL,asl.dir,NIL,asl.leftEdge,20,asl.topEdge,20,
asl.width,300,asl.height,200,u.done,NIL);
tags[0].data := hail;
tags[1].data := edG.Text.window;
tags[2].data := sys.ADR(Filename);
tags[3].data := sys.ADR(Dirname);
fr := asl.AllocAslRequest(asl.fileRequest,tags);
IF fr=NIL THEN EXIT END;
res := asl.RequestFile(fr);
COPY(fr.dir^,Dirname);
COPY(fr.file^,Filename);
asl.FreeFileRequest(fr);
IF NOT res THEN EXIT END;
ELSE
FR.hail := hail;
FR.file := sys.ADR(Filename);
FR.dir := sys.ADR(Dirname);
FR.window := edG.Text.window;;
FR.funcFlags:= SHORTSET{};
FR.flags2 := SHORTSET{longPath};
FR.function := NIL;
FR.leftEdge := 0;
FR.topEdge := 0;
IF NOT FileRequest(sys.ADR(FR)) THEN EXIT END;
END;
j := str.Length(Dirname);
IF (j>0) AND (Dirname[j-1]#"/") AND (Dirname[j-1]#":") THEN
Dirname[j] := "/"; INC(j);
Dirname[j] := 0X;
END;
IF sys.SIZE(Filename)>j+str.Length(Filename) THEN
str.Insert(Filename,0,Dirname);
RETURN TRUE;
END;
END;
RETURN FALSE;
END FileReq;
PROCEDURE GetPathAndName(string: ARRAY OF CHAR; (* $CopyArrays- *)
VAR path, name: ARRAY OF CHAR);
(* <string> kann die gleiche Var sein wie <path> *)
VAR
i: INTEGER;
BEGIN
i := str.Length(string);
WHILE (i > 0) AND (string[i]#"/") AND (string[i]#":") DO
DEC(i);
END;
str.Cut(string,i+1,LEN(name),name);
str.Cut(string,0,i,name);
END GetPathAndName;
(*-----------------------------------------------------------------------*)
(*
(* Lädt File <Name> in <List>, <Num> ist Anzahl geladener Zeilen *)
PROCEDURE LoadLines*(VAR List: lst.List; Source: BOOLEAN;
(* $CopyArrays- *)
Name: ARRAY OF CHAR): LONGINT;
VAR
len: INTEGER;
newLine: edG.LinePtr;
Buffer: edG.StringPtr;
Num: LONGINT;
File: fs.File;
BEGIN
ol.New(Buffer,sys.SIZE(edG.String));
IF Buffer=NIL THEN
INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
RETURN -1;
END;
Buffer^ := "";
IF NOT fs.Open(File,Name,FALSE) THEN
DISPOSE(Buffer); RETURN -1; END;
Num := 0;
LOOP
IF NOT fs.ReadString(File,Buffer^) THEN
IF File.status # fs.eof THEN
edG.Rc := edE.cmdSevere; edL.Title(ReadError);
Num := -1;
END;
EXIT;
END;
IF Source THEN
IF Buffer^ # "" THEN
Num := 0;
REPEAT
IF Buffer[Num]=ASCII.ht THEN Buffer[Num] := 20X; END;
INC(Num);
UNTIL (Num = edG.MaxLineLength) OR (Buffer[Num] = 0X);
edG.ExecCmd(Buffer);
END;
ELSE
len := str.Length(Buffer^);
REPEAT
DEC(len);
UNTIL (len < 0) OR (Buffer[len]#20X);
INC(len);
Buffer[len] := 0X;
len := len+edG.MemStepSize-(len MOD edG.MemStepSize);
edL.NewLine(newLine,len);
IF newLine#NIL THEN
e.CopyMem(Buffer^,newLine(edG.Line).string^,len);
lst.AddTail(List,newLine);
INC(Num);
ELSE
INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
Num := -1;
END; (* IF newLine # NIL *)
END;
IF Num < 0 THEN (* MemoryFailed *)
EXIT; END;
END; (* LOOP *)
IF fs.Close(File) THEN END;
DISPOSE(Buffer);
RETURN Num;
END LoadLines;
*)
(* NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW *)
(* $CopyArrays- *)
PROCEDURE FastLoadLines(VAR list:lst.List;name:ARRAY OF CHAR):LONGINT;
CONST
BlockSize = 10000;
MaxLineSize = edG.LineAllocSize + edG.MaxLineLength;
ChunkSize = sys.SIZE(e.MemChunk);
VAR
line:POINTER TO edG.Line;
node:lst.NodePtr;
end:e.ADDRESS;
file:fs.File;
len:LONGINT;
num:LONGINT;
BEGIN
IF NOT fs.Open(file,name,FALSE) THEN
RETURN -1
END; (* IF *)
lst.Init(list);
line := NIL;
num := 0;
REPEAT
(* do we need more memory ? *)
IF (line = NIL) OR
(sys.VAL(LONGINT,line) > (end - MaxLineSize)) THEN
(* free unused memory of last block *)
IF line # NIL THEN
e.FreeMem(line,sys.VAL(LONGINT,end)-sys.VAL(LONGINT,line));
END; (* IF *)
(* get new memory block *)
line := e.AllocMem(BlockSize,LONGSET{});
IF line = NIL THEN
(* free memory used so far *)
node := lst.RemHead(list);
WHILE node # NIL DO
WITH node:edG.Line DO
e.FreeMem(node.string,node.len+edG.LineAllocSize);
END;
node := lst.RemHead(list);
END; (* WHILE *)
IF fs.Close(file) THEN END;
INCL(edG.Status,edG.memoryFail);
edG.Rc := edE.cmdSevere;
RETURN -1;
END;
end := line; INC(end,BlockSize);
END; (* IF *)
(* read line *) (* $TypeChk- *)
sys.INIT(line); (* $TypeChk= *)
line.string := sys.VAL(LONGINT,line) + edG.LineAllocSize;
len := fs.ReadStringLenTab(file,line.string^,8);
IF len >= 0 THEN
line.string[len] := "\o";
line.len := SHORT(len + ChunkSize-(len MOD ChunkSize));
lst.AddTail(list,line);
INC(line,line.len + edG.LineAllocSize);
INC(num);
END; (* IF *)
UNTIL (len = -1);
IF sys.VAL(LONGINT,line) < end THEN
e.FreeMem(line,sys.VAL(LONGINT,end)-sys.VAL(LONGINT,line));
END; (* IF *)
IF fs.Close(file) THEN END;
RETURN num;
END FastLoadLines;
PROCEDURE doLoad*;
VAR
oldlock: d.FileLockPtr;
NumNewLines: LONGINT;
TempLine: edG.LinePtr;
NewList: lst.List;
BEGIN
edD.PutBackLine;
IF (newFile IN edG.ArgSet) THEN
IF (edG.modified IN edG.Text.status)
AND NOT I.AutoRequest(edG.Text.window,ReqBody,sys.ADR(ReqOkay),ReqCancel,
LONGSET{},LONGSET{},320,58)
THEN
edG.Rc := edE.cmdValid1; RETURN;
END;
e.CopyMemQuick(edG.Arg[0]^,edG.Text.name,edG.FileNameLength);
edG.Text.name[edG.FileNameLength-1] := 0X;
edB.doUnblock;
END;
oldlock := d.CurrentDir(edG.Text.dirLock);
edL.Title(Loading); edG.Rc := edE.cmdValid2;
NumNewLines := FastLoadLines(NewList,edG.Arg[0]^);
IF NumNewLines = -1 THEN
IF edG.Rc < edE.FailLevel THEN
edG.Rc := edE.cmdError; edL.Title(FileNotFound);
END;
RETURN;
END;
edL.Title(edG.Okay);
oldlock := d.CurrentDir(oldlock);
(* Newfile oder leeres File *)
IF (newFile IN edG.ArgSet) OR (edG.Text.actLinePtr(edG.Line).string^ = "")
AND (edG.Text.numberOfLines=1) THEN
edL.FreeLines(edG.Text.lineList,edG.Text.lineList.head(edG.Line),
edG.Text.lineList.tail(edG.Line));
END;
IF edG.Text.lineList.head=NIL THEN
edG.Text.line := 0; edG.Text.pos := 0; edG.Text.topLine := 0;
EXCL(edG.Text.status,edG.modified);
IF NewList.head#NIL THEN
edG.Text.numberOfLines := NumNewLines;
lst.AddMarkHead(edG.Text.lineList,NewList);
ELSE
edG.Text.numberOfLines := 1;
edL.NewLine(TempLine,edG.ChunkSize);
lst.AddHead(edG.Text.lineList,TempLine);
END;
edG.Text.actLinePtr := edG.Text.lineList.head(edG.Line);
edG.Text.topLinePtr := edG.Text.actLinePtr;
ELSE
INC(edG.Text.numberOfLines,NumNewLines);
lst.AddMarkBefore(edG.Text.lineList,NewList,edG.Text.actLinePtr);
INCL(edG.Text.status,edG.modified);
edG.Text.actLinePtr := NewList.head(edG.Line);
IF edG.Text.line = edG.Text.topLine THEN
edG.Text.topLinePtr := edG.Text.actLinePtr; END;
END;
edD.TextLoad;
edD.SetWindowParams;
edD.TextRedisplay;
END doLoad;
PROCEDURE doSource*;
VAR
len: INTEGER;
Buffer: edG.StringPtr;
File: fs.File;
BEGIN
ol.New(Buffer,sys.SIZE(edG.String));
IF Buffer=NIL THEN
INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
RETURN;
END;
IF fs.Open(File,edG.Arg[0]^,FALSE) THEN
LOOP
len := fs.ReadStringLen(File,Buffer^);
IF len = -1 THEN
IF File.status # fs.eof THEN
edG.Rc := edE.cmdSevere; edL.Title(ReadError);
END;
EXIT;
ELSIF len # 0 THEN
REPEAT
DEC(len);
IF Buffer[len]=ASCII.ht THEN Buffer[len] := 20X; END;
UNTIL len = 0;
edG.ExecCmd(Buffer);
END;
END; (* LOOP *)
IF fs.Close(File) THEN END;
ELSIF NOT (sourceDoNotTitle IN edG.ArgSet) THEN
edG.Rc := edE.cmdError; edL.Title(FileNotFound);
END;
DISPOSE(Buffer);
END doSource;
(*-----------------------------------------------------------------------*)
PROCEDURE SaveLines(Name: ARRAY OF CHAR; start,end: edG.LinePtr);
VAR
next: edG.LinePtr;
File: fs.File;
ok: BOOLEAN;
i, j, k: INTEGER;
ptr: e.STRPTR;
BEGIN
IF NOT fs.Open(File,Name,TRUE) THEN
edL.Title(UnableToOpenFile); edG.Rc := edE.cmdSevere;
RETURN;
END;
REPEAT
IF edG.saveTabs IN edG.Text.status THEN
ptr := sys.VAL(e.STRPTR,start(edG.Line).string);
i := 0; j := 0;
WHILE ptr^[0] # "\o" DO
Dirname[i] := ptr^[0];
IF (j = 7) AND (Dirname[i] = ' ') AND (Dirname[i-1] = ' ') THEN
k := j;
WHILE (k >= 0) AND (Dirname[i] = ' ') DO
DEC(k);
DEC(i);
END;
INC(i);
Dirname[i] := "\t";
ELSE
CASE Dirname[i] OF
"\"", "\'", "\`", "(":
j := str.Length(ptr^);
e.CopyMem(ptr^,Dirname[i],j+1);
INC(ptr,j); INC(i,j);
ELSE END;
END;
INC(ptr);
INC(i);
j := (j+1) MOD 8;
END;
Dirname[i] := "\o";
ok := fs.WriteString(File,Dirname);
ELSE
ok := fs.WriteString(File,start(edG.Line).string^);
END;
IF ok AND (start # end) THEN
start := start.next(edG.Line);
ELSE
start := NIL;
END;
UNTIL start = NIL;
IF ok THEN
edL.Title(edG.Okay); edG.Rc := edE.cmdValid2;
ELSE
edL.Title(WriteFailed); edG.Rc := edE.cmdSevere;
END;
ok := fs.Close(File);
END SaveLines;
PROCEDURE doSave*;
VAR
SaveList: lst.List;
BEGIN
edD.PutBackLine;
SaveList := edG.Text.lineList;
IF (saveBlock IN edG.ArgSet) THEN
IF NOT edB.BlockSpecified() THEN RETURN; END;
e.CopyMem(edG.Block,SaveList,sys.SIZE(SaveList));
ELSIF NOT (saveAs IN edG.ArgSet) THEN
edG.Arg[0] := sys.ADR(edG.Text.name);
END;
SaveLines(edG.Arg[0]^,SaveList.head(edG.Line),SaveList.tail(edG.Line));
IF (edG.Rc < edE.cmdFailed) THEN
IF NOT (saveBlock IN edG.ArgSet) THEN
EXCL(edG.Text.status,edG.modified);
ELSIF saveAs IN edG.ArgSet THEN
GetPathAndName(edG.Arg[0]^,edG.Arg[0]^,edG.Text.name);
END;
END;
END doSave;
(*-----------------------------------------------------------------------*)
PROCEDURE doFileReq*;
VAR
doDo: edG.ComProc;
hail: edG.StringPtr;
BEGIN
IF edG.fileReqAvail IN edG.Status THEN
Filename := "";
IF saveAs IN edG.ArgSet THEN
hail := sys.ADR(SaveAs);
doDo := doSave;
e.CopyMemQuick(edG.Text.name,Filename,edG.FileNameLength);
ELSIF saveBlock IN edG.ArgSet THEN
IF NOT edB.BlockSpecified() THEN RETURN; END;
hail := sys.ADR(SaveBlock);
doDo := doSave;
ELSIF newFile IN edG.ArgSet THEN
hail := sys.ADR(NewFile);
doDo := doLoad;
ELSE
hail := sys.ADR(InsFile);
doDo := doLoad;
END;
IF FileReq(hail) THEN
edG.Arg[0] := sys.ADR(Filename);
doDo;
ELSE
edG.Rc := edE.cmdValid1;
END;
ELSE
edL.Title(FileReqNotAvailable); edG.Rc := edE.cmdError;
END;
END doFileReq;
(*-----------------------------------------------------------------------*)
PROCEDURE doChFilename*;
BEGIN
e.CopyMemQuick(edG.Arg[0]^,edG.Text.name,edG.FileNameLength);
END doChFilename;
PROCEDURE doCD*;
VAR
oldLock, Lock: d.FileLockPtr;
BEGIN
oldLock := d.CurrentDir(edG.Text.dirLock);
Lock := d.Lock(edG.Arg[0]^,d.sharedLock);
IF Lock # NIL THEN
d.UnLock(d.CurrentDir(oldLock));
edG.Text.dirLock := Lock;
ELSE
IF d.CurrentDir(oldLock)=NIL THEN END;
edG.Rc := edE.cmdFailed; edL.Title(UnableToCD);
END;
END doCD;
(*-----------------------------------------------------------------------*)
PROCEDURE doSaveMap*;
VAR
ptr: edG.StringPtr;
hash: edK.HashPtr;
i,len : INTEGER;
soc, eoc, ksoc, keoc: CHAR;
sysalso: BOOLEAN;
File: fs.File;
Buffer: edG.String;
BEGIN
IF NOT fs.Open(File,edG.Arg[0]^,TRUE) THEN
edL.Title(UnableToOpenFile); edG.Rc := edE.cmdSevere;
RETURN;
END;
sysalso := saveSysMap IN edG.ArgSet;
i := 0;
REPEAT
hash := edK.HashList[i];
WHILE hash # NIL DO
IF (hash.len # 0) OR sysalso THEN
soc := "("; eoc := ")"; ksoc := "("; keoc := ")";
ptr := hash.map;
LOOP
IF (ptr[0] = 0X) OR (ptr[0] = "(") THEN EXIT; END;
IF ptr^ = "`" THEN
soc := "`"; eoc := "'";
EXIT;
END;
INC(ptr);
END; (* LOOP *)
ptr := edK.cqTOa(hash.code,hash.qual);
len := str.Length(ptr^)-1;
IF (ptr[len] = "(") OR (ptr[len] = ")") THEN
ksoc := "`"; keoc := "'"; END;
Printf.SPrintf6(Buffer,"map %lc%s%lc %lc%s%lc",
ORD(ksoc),ptr,ORD(keoc),ORD(soc),hash.map,ORD(eoc));
IF NOT fs.WriteString(File,Buffer) THEN
IF fs.Close(File) THEN END;
edL.Title(WriteFailed); edG.Rc := edE.cmdSevere;
RETURN;
END;
END; (* IF hash.len#0 ... *)
hash := hash.next;
END; (* WHILE *)
INC(i);
UNTIL i = edK.Hashsize;
IF fs.Close(File) THEN END;
edL.Title(edG.Okay);
END doSaveMap;
(*-----------------------------------------------------------------------*)
PROCEDURE GetConfig*;
VAR
config: fs.File;
BEGIN
e.CopyMemQuick(edG.StdWindow,edG.Config.edges,sys.SIZE(edG.Config.edges));
edG.Config.screenDepth := 0;
IF fs.Open(config,ConfigFileName,FALSE) THEN
IF NOT fs.Read(config,edG.Config) THEN
CASE config.status OF
fs.toofar, fs.eof:|
ELSE
edL.Title(ReadError); edG.Rc := edE.cmdSevere;
END;
END;
IF fs.Close(config) THEN END;
END;
END GetConfig;
PROCEDURE doSaveConfig*;
VAR
win: I.WindowPtr;
config: fs.File;
BEGIN
IF fs.Open(config,ConfigFileName,TRUE) THEN
e.CopyMemQuick(edG.Text.window.leftEdge,
edG.Config.edges,sys.SIZE(edG.Config.edges));
IF NOT fs.Write(config,edG.Config) THEN
edL.Title(WriteFailed); edG.Rc := edE.cmdSevere; END;
IF fs.Close(config) THEN END;
END;
END doSaveConfig;
(*-----------------------------------------------------------------------*)
BEGIN
INCL(edG.Status,edG.fileReqAvail);
IF asl.asl=NIL THEN
arpbase := e.OpenLibrary("arp.library",39);
IF arpbase = NIL THEN
EXCL(edG.Status,edG.fileReqAvail);
END;
END;
CLOSE
IF arpbase#NIL THEN e.CloseLibrary(arpbase) END;
END EdFileTools.